package com.scopicsoftware.tctruc.creativecowcrawler;

import java.awt.image.BufferedImage;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;

import org.imgscalr.Scalr;
import org.imgscalr.Scalr.Method;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import au.com.bytecode.opencsv.CSVWriter;

import com.scopicsoftware.tctruc.creativecowcrawler.object.Country;

public class Crawler {

	private static final String CREATIVECOW_URL = "http://services.creativecow.net";
	private Document document;
	Tesseract instance;

	public Crawler() throws IOException {

	}

	public ArrayList<Country> crawCountry() throws IOException {

		System.out.println("Start crawling countries");
		document = Jsoup.connect(CREATIVECOW_URL).timeout(10000).get();
		ArrayList<Country> countryList = new ArrayList<Country>();
		// Get all country links
		Elements countryLinks = document
				.select("a[href^=http://services.creativecow.net/country/]");

		for (Element countryLink : countryLinks) {
			Country c = new Country();
			c.setCountryLink(countryLink.attr("href"));
			c.setCountryName(countryLink.select("img").first().attr("title"));
			countryList.add(c);
			System.out.println("Added country: "+c.getCountryName());
		}
		System.out.println("Finished crawling countries");

		return countryList;
	}
	
	public void crawProfile() throws IOException {
		String csvOutput = "C:\\creativecow_profiles.csv";
		CSVWriter csvWriter = new CSVWriter(new FileWriter(csvOutput));
		List<String[]> profiles = new ArrayList<String[]>();
		
		ArrayList<Country> countries = this.crawCountry();
		for(Country country : countries)
		{
			document = Jsoup.connect(country.getCountryLink()).timeout(10000).get();
			Elements profileList = document.select("div[class=container bg3]");
			for(Element profile : profileList) {
				
				Element profileWrapper = profile.children().select("div").first();
				
				String name = profileWrapper.children().select("div").get(2).text();
				String address = profileWrapper.children().select("div").get(0).text();
				String category = profileWrapper.children().select("div").get(1).text();
				String expertise = profileWrapper.children().select("div").get(3).text();
				String profileURL = profileWrapper.children().select("div").get(2).children().select("a").attr("href");
				String crawledEmail = this.crawEmail(profileURL.split("/")[4]);
				
				// Debug
				System.out.println("--------------------------------------------");
				System.out.println("Name: "+name);
				System.out.println("Address: "+address);
				System.out.println("Category: "+category);
				System.out.println("Expertise: "+expertise);
				System.out.println("Email: "+crawledEmail);
				System.out.println("ProfileURL: "+profileURL);
				System.out.println("--------------------------------------------");
				
				profiles.add(new String[] {name,address,category,expertise,crawledEmail,profileURL});
			}
		}
		csvWriter.writeAll(profiles);
		csvWriter.close();
	}

	public String crawEmail(String profileID) throws IOException {
		// String csvOutput = "D:\\creativecow_emails.csv";
		// CSVWriter csvWriter = new CSVWriter(new FileWriter(csvOutput));
		// List<String[]> emails = new ArrayList<String[]>();

		instance = Tesseract.getInstance();
		//instance.setTessVariable("tessedit_char_blacklist", "|");
		// OCR-ed email
		String ocredEmail = "";
		// Link for crawling email
		 String emailURL = "http://library.creativecow.net/docs/captcha-image_services_email.php?id="+profileID;
		// Read image
		BufferedImage inputImage = ImageIO.read(new URL(emailURL));
		// Resize for easier ocr
		BufferedImage bi = Scalr.resize(inputImage, Method.QUALITY, 1145);
		// Start OCR process

		try {
			ocredEmail = instance.doOCR(bi);
			// Removes "Email: " part, replaces "|" character with "l" character
			// and some useless white spaces
			ocredEmail = ocredEmail.replaceFirst("Email:", "").trim();
			ocredEmail = replaceDividerSignstring(ocredEmail);
			ocredEmail = ocredEmail.replace(" ", "");
			// Reset emptyCounter
			// emails.add(new String[] {ocredEmail,emailLink + ""+ emailID});
		} catch (TesseractException e) {
			System.err.println(e.getMessage());
		}
		
		return ocredEmail;
	}

	public String replaceDividerSignstring(String email) {
		StringBuilder emailString = new StringBuilder(email);
		for (int i = 0; i < emailString.length(); i++) {
			if (emailString.charAt(i) == '|') {
				if (i == 0) {
					if (Character.isUpperCase(emailString.charAt(i + 1))) {
						emailString.setCharAt(i, 'I');
					} else {
						emailString.setCharAt(i, 'l');
					}
				} else if (Character.isUpperCase(emailString.charAt(i - 1)) && Character.isUpperCase(emailString.charAt(i + 1))) {
					emailString.setCharAt(i, 'I');
				} else if ((i + 1) > emailString.length()) {
					if (Character.isUpperCase(emailString.charAt(i - 1))) {
						emailString.setCharAt(i, 'I');
					} else {
						emailString.setCharAt(i, 'l');
					}
				} else {
					emailString.setCharAt(i, 'l');
				}
			} else if(emailString.charAt(i) == 'I') {
				if (i == 0) {
					if (!Character.isUpperCase(emailString.charAt(i + 1))) {
						emailString.setCharAt(i, 'l');
					} else {
						emailString.setCharAt(i, 'I');
					}
				} else if (!Character.isUpperCase(emailString.charAt(i - 1)) && !Character.isUpperCase(emailString.charAt(i + 1))) {
					emailString.setCharAt(i, 'l');
				} else if ((i + 1) > emailString.length()) {
					if (!Character.isUpperCase(emailString.charAt(i - 1))) {
						emailString.setCharAt(i, 'l');
					} else {
						emailString.setCharAt(i, 'I');
					}
				} else {
					emailString.setCharAt(i, 'I');
				}
			}
		}
		return emailString.toString();
	}
}
